package auth

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

// Handler 认证处理器
type Handler struct {
	service Service
}

// NewHandler 创建认证处理器
func NewHandler(service Service) *Handler {
	return &Handler{service: service}
}

// Login 用户登录
// @Summary 用户登录
// @Description 用户登录接口
// @Tags 认证
// @Accept json
// @Produce json
// @Param request body LoginRequest true "登录请求"
// @Success 200 {object} TokenInfo "登录成功"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Failure 401 {object} ErrorResponse "认证失败"
// @Router /api/v1/auth/login [post]
func (h *Handler) Login(c *gin.Context) {
	var req LoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的请求参数",
			Error:   err.Error(),
		})
		return
	}

	token, err := h.service.Login(req.Username, req.Password)
	if err != nil {
		status := http.StatusUnauthorized
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "登录失败",
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, token)
}

// RefreshToken 刷新令牌
// @Summary 刷新令牌
// @Description 刷新访问令牌
// @Tags 认证
// @Accept json
// @Produce json
// @Param request body RefreshTokenRequest true "刷新令牌请求"
// @Success 200 {object} TokenInfo "刷新成功"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Failure 401 {object} ErrorResponse "认证失败"
// @Router /api/v1/auth/refresh [post]
func (h *Handler) RefreshToken(c *gin.Context) {
	var req RefreshTokenRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的请求参数",
			Error:   err.Error(),
		})
		return
	}

	token, err := h.service.RefreshToken(req.RefreshToken)
	if err != nil {
		status := http.StatusUnauthorized
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "刷新令牌失败",
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, token)
}

// GetUser 获取用户信息
// @Summary 获取用户信息
// @Description 获取指定用户的详细信息
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param id path int true "用户ID"
// @Success 200 {object} UserDTO "用户信息"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Failure 404 {object} ErrorResponse "用户不存在"
// @Router /api/v1/users/{id} [get]
func (h *Handler) GetUser(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的用户ID",
			Error:   err.Error(),
		})
		return
	}

	user, err := h.service.GetUser(uint(id))
	if err != nil {
		status := http.StatusNotFound
		if err == ErrUserNotFound {
			c.JSON(status, ErrorResponse{
				Code:    status,
				Message: "用户不存在",
				Error:   err.Error(),
			})
			return
		}

		status = http.StatusInternalServerError
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "获取用户信息失败",
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, user)
}

// CreateUser 创建用户
// @Summary 创建用户
// @Description 创建新用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param request body CreateUserRequest true "创建用户请求"
// @Success 201 {object} UserDTO "创建成功"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Router /api/v1/users [post]
func (h *Handler) CreateUser(c *gin.Context) {
	var req CreateUserRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的请求参数",
			Error:   err.Error(),
		})
		return
	}

	user, err := h.service.CreateUser(&req)
	if err != nil {
		status := http.StatusBadRequest
		if err == ErrUserAlreadyExists {
			c.JSON(status, ErrorResponse{
				Code:    status,
				Message: "用户已存在",
				Error:   err.Error(),
			})
			return
		}

		status = http.StatusInternalServerError
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "创建用户失败",
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusCreated, user)
}

// UpdateUser 更新用户
// @Summary 更新用户
// @Description 更新用户信息
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param id path int true "用户ID"
// @Param request body UpdateUserRequest true "更新用户请求"
// @Success 200 {object} UserDTO "更新成功"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Failure 404 {object} ErrorResponse "用户不存在"
// @Router /api/v1/users/{id} [put]
func (h *Handler) UpdateUser(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的用户ID",
			Error:   err.Error(),
		})
		return
	}

	var req UpdateUserRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的请求参数",
			Error:   err.Error(),
		})
		return
	}

	user, err := h.service.UpdateUser(uint(id), &req)
	if err != nil {
		status := http.StatusNotFound
		if err == ErrUserNotFound {
			c.JSON(status, ErrorResponse{
				Code:    status,
				Message: "用户不存在",
				Error:   err.Error(),
			})
			return
		}

		status = http.StatusInternalServerError
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "更新用户失败",
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, user)
}

// DeleteUser 删除用户
// @Summary 删除用户
// @Description 删除指定用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param id path int true "用户ID"
// @Success 204 "删除成功"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Failure 404 {object} ErrorResponse "用户不存在"
// @Router /api/v1/users/{id} [delete]
func (h *Handler) DeleteUser(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的用户ID",
			Error:   err.Error(),
		})
		return
	}

	if err := h.service.DeleteUser(uint(id)); err != nil {
		status := http.StatusNotFound
		if err == ErrUserNotFound {
			c.JSON(status, ErrorResponse{
				Code:    status,
				Message: "用户不存在",
				Error:   err.Error(),
			})
			return
		}

		status = http.StatusInternalServerError
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "删除用户失败",
			Error:   err.Error(),
		})
		return
	}

	c.Status(http.StatusNoContent)
}

// ListUsers 查询用户列表
// @Summary 查询用户列表
// @Description 分页查询用户列表
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param tenant_id query int false "租户ID"
// @Param username query string false "用户名"
// @Param status query int false "状态"
// @Param page_num query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Success 200 {object} ListResponse "用户列表"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Router /api/v1/users [get]
func (h *Handler) ListUsers(c *gin.Context) {
	query := &UserQuery{
		PageNum:  1,
		PageSize: 10,
	}

	// 解析查询参数
	if tenantID, err := strconv.ParseUint(c.Query("tenant_id"), 10, 32); err == nil {
		query.TenantID = uint(tenantID)
	}

	query.Username = c.Query("username")

	if status, err := strconv.Atoi(c.Query("status")); err == nil {
		statusVal := status
		query.Status = &statusVal
	}

	if pageNum, err := strconv.Atoi(c.Query("page_num")); err == nil && pageNum > 0 {
		query.PageNum = pageNum
	}

	if pageSize, err := strconv.Atoi(c.Query("page_size")); err == nil && pageSize > 0 {
		query.PageSize = pageSize
	}

	users, total, err := h.service.ListUsers(query)
	if err != nil {
		status := http.StatusInternalServerError
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "查询用户列表失败",
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, ListResponse{
		Total: total,
		Items: users,
	})
}

// GetRole 获取角色信息
// @Summary 获取角色信息
// @Description 获取指定角色的详细信息
// @Tags 角色管理
// @Accept json
// @Produce json
// @Param id path int true "角色ID"
// @Success 200 {object} RoleDTO "角色信息"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Failure 404 {object} ErrorResponse "角色不存在"
// @Router /api/v1/roles/{id} [get]
func (h *Handler) GetRole(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的角色ID",
			Error:   err.Error(),
		})
		return
	}

	role, err := h.service.GetRole(uint(id))
	if err != nil {
		status := http.StatusNotFound
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "角色不存在",
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, role)
}

// CreateRole 创建角色
// @Summary 创建角色
// @Description 创建新角色
// @Tags 角色管理
// @Accept json
// @Produce json
// @Param request body CreateRoleRequest true "创建角色请求"
// @Success 201 {object} RoleDTO "创建成功"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Router /api/v1/roles [post]
func (h *Handler) CreateRole(c *gin.Context) {
	var req CreateRoleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的请求参数",
			Error:   err.Error(),
		})
		return
	}

	role, err := h.service.CreateRole(&req)
	if err != nil {
		status := http.StatusBadRequest
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "创建角色失败",
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusCreated, role)
}

// UpdateRole 更新角色
// @Summary 更新角色
// @Description 更新角色信息
// @Tags 角色管理
// @Accept json
// @Produce json
// @Param id path int true "角色ID"
// @Param request body UpdateRoleRequest true "更新角色请求"
// @Success 200 {object} RoleDTO "更新成功"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Failure 404 {object} ErrorResponse "角色不存在"
// @Router /api/v1/roles/{id} [put]
func (h *Handler) UpdateRole(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的角色ID",
			Error:   err.Error(),
		})
		return
	}

	var req UpdateRoleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的请求参数",
			Error:   err.Error(),
		})
		return
	}

	role, err := h.service.UpdateRole(uint(id), &req)
	if err != nil {
		status := http.StatusNotFound
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "角色不存在或更新失败",
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, role)
}

// DeleteRole 删除角色
// @Summary 删除角色
// @Description 删除指定角色
// @Tags 角色管理
// @Accept json
// @Produce json
// @Param id path int true "角色ID"
// @Success 204 "删除成功"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Failure 404 {object} ErrorResponse "角色不存在"
// @Router /api/v1/roles/{id} [delete]
func (h *Handler) DeleteRole(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的角色ID",
			Error:   err.Error(),
		})
		return
	}

	if err := h.service.DeleteRole(uint(id)); err != nil {
		status := http.StatusNotFound
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "角色不存在或删除失败",
			Error:   err.Error(),
		})
		return
	}

	c.Status(http.StatusNoContent)
}

// ListRoles 查询角色列表
// @Summary 查询角色列表
// @Description 分页查询角色列表
// @Tags 角色管理
// @Accept json
// @Produce json
// @Param tenant_id query int false "租户ID"
// @Param name query string false "角色名称"
// @Param code query string false "角色编码"
// @Param status query int false "状态"
// @Param page_num query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Success 200 {object} ListResponse "角色列表"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Router /api/v1/roles [get]
func (h *Handler) ListRoles(c *gin.Context) {
	query := &RoleQuery{
		PageNum:  1,
		PageSize: 10,
	}

	// 解析查询参数
	if tenantID, err := strconv.ParseUint(c.Query("tenant_id"), 10, 32); err == nil {
		query.TenantID = uint(tenantID)
	}

	query.Name = c.Query("name")
	query.Code = c.Query("code")

	if status, err := strconv.Atoi(c.Query("status")); err == nil {
		statusVal := status
		query.Status = &statusVal
	}

	if pageNum, err := strconv.Atoi(c.Query("page_num")); err == nil && pageNum > 0 {
		query.PageNum = pageNum
	}

	if pageSize, err := strconv.Atoi(c.Query("page_size")); err == nil && pageSize > 0 {
		query.PageSize = pageSize
	}

	roles, total, err := h.service.ListRoles(query)
	if err != nil {
		status := http.StatusInternalServerError
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "查询角色列表失败",
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, ListResponse{
		Total: total,
		Items: roles,
	})
}

// GetUserRoles 获取用户角色
// @Summary 获取用户角色
// @Description 获取指定用户的角色列表
// @Tags 用户角色管理
// @Accept json
// @Produce json
// @Param user_id path int true "用户ID"
// @Success 200 {array} RoleDTO "角色列表"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Router /api/v1/users/{user_id}/roles [get]
func (h *Handler) GetUserRoles(c *gin.Context) {
	userID, err := strconv.ParseUint(c.Param("user_id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的用户ID",
			Error:   err.Error(),
		})
		return
	}

	roles, err := h.service.GetUserRoles(uint(userID))
	if err != nil {
		status := http.StatusInternalServerError
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "获取用户角色失败",
			Error:   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, roles)
}

// AssignRolesToUser 为用户分配角色
// @Summary 为用户分配角色
// @Description 为指定用户分配角色
// @Tags 用户角色管理
// @Accept json
// @Produce json
// @Param user_id path int true "用户ID"
// @Param request body AssignRolesRequest true "分配角色请求"
// @Success 204 "分配成功"
// @Failure 400 {object} ErrorResponse "请求错误"
// @Router /api/v1/users/{user_id}/roles [post]
func (h *Handler) AssignRolesToUser(c *gin.Context) {
	userID, err := strconv.ParseUint(c.Param("user_id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的用户ID",
			Error:   err.Error(),
		})
		return
	}

	var req AssignRolesRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{
			Code:    400,
			Message: "无效的请求参数",
			Error:   err.Error(),
		})
		return
	}

	if err := h.service.AssignRolesToUser(uint(userID), req.RoleIDs); err != nil {
		status := http.StatusInternalServerError
		c.JSON(status, ErrorResponse{
			Code:    status,
			Message: "分配角色失败",
			Error:   err.Error(),
		})
		return
	}

	c.Status(http.StatusNoContent)
}

// LoginRequest 登录请求
type LoginRequest struct {
	Username string `json:"username" binding:"required"`
	Password string `json:"password" binding:"required"`
}

// RefreshTokenRequest 刷新令牌请求
type RefreshTokenRequest struct {
	RefreshToken string `json:"refresh_token" binding:"required"`
}

// AssignRolesRequest 分配角色请求
type AssignRolesRequest struct {
	RoleIDs []uint `json:"role_ids" binding:"required"`
}

// ErrorResponse 错误响应
type ErrorResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Error   string `json:"error,omitempty"`
}

// ListResponse 列表响应
type ListResponse struct {
	Total int64       `json:"total"`
	Items interface{} `json:"items"`
}
